import { ref } from "vue";
import { get, has, defaults } from "lodash-es";
import { usePagination } from "./paginationHooks";
type keyPath = Array<string> | string;

export function useTable<T>(
    api: (params: any) => Promise<T>,
    options: {
      path: { data: keyPath; total: keyPath; page?: string; size?: string }
      immediate: boolean
    },
    params?: object | (() => object),
  ) {
    defaults(options, { // defaults，将后面参数的属性，赋值到第一个对象的值为 undefined 的属性上，用于初始化函数参数。
      path: { data: 'data', total: 'total', page: 'page', size: 'size' },
      immediate: false,
    })
  
    // 使用()=>fn()而不是fn()区别在于后者只是一个值且立即执行
    const [pagination, , , setTotal] = usePagination((extraData?: object) =>
      extraData ? refresh(extraData) : refresh(),
    )
    const loading = ref(false)
    const data = ref([])
  
    const refresh = (extraData?: object | (() => object)) => {
      const requestData = {
        [options?.path?.page as string]: pagination.current,
        [options?.path?.size as string]: pagination.size,
      }
      if (extraData) { // refresh 方法内的传参：refresh({ id: 1 })
        if (typeof extraData === 'function') {
          Object.assign(requestData, extraData())
        } else {
          Object.assign(requestData, extraData)
        }
      }
      if (params) { // useTable 方法内的传参
        if (typeof params === 'function') {
          Object.assign(requestData, params())
        } else {
          Object.assign(requestData, params)
        }
      }
      console.log(requestData)
      loading.value = true
      return api(requestData)
        .then((res) => {
          // TODO 检查响应状态码
          data.value = get(res, options!.path?.data, []) // get，获取对象属性，如果为 undefined，使用第三个参数的值。
          setTotal(get(res, options!.path?.total, 0))
          // 友好提示
          if (!has(res, options!.path?.data) || !has(res, options!.path?.total)) { // has，判断对象属性。
            console.warn('useTable：响应数据缺少所需字段')
          }
        })
        .finally(() => {
          loading.value = false
        })
    }
  
   return[data, refresh, pagination, loading]

}